package cron

import (
	"bigdevops/src/common"
	"bigdevops/src/models"
	"context"
	"go.uber.org/zap"
	"k8s.io/apimachinery/pkg/util/wait"
	"time"
)

// wait.UntilWithContext k8s 基础库 每隔多长时间去执行一次任务
func (cm *CronManager) FullFillOnDutyHistoryManager(ctx context.Context) error {
	// 每隔 多长时间去执行一下 RunSyncCloudResource ，直到 ctx.Done
	go wait.UntilWithContext(ctx, cm.FullFillOnDutyHistory, 5*time.Minute)
	<-ctx.Done()
	cm.Sc.Logger.Info("FullFillOnDutyHistory 收到其他任务退出信号 退出")
	return nil

}

// 填充值班历史表
func (cm *CronManager) FullFillOnDutyHistory(ctx context.Context) {

	// 拿出所有的值班组
	groups, err := models.GetMonitorOndutyGroupAll()
	if err != nil {
		cm.Sc.Logger.Error("[值班组历史]扫描数据库中值班组失败",
			zap.Error(err),
		)
		return
	}

	for _, group := range groups {
		group := group
		if group.Members == nil {
			continue
		}
		go cm.FullFillOnDutyHistoryOnGroup(group)
	}
}

// 每天凌晨第一次执行
func (cm *CronManager) FullFillOnDutyHistoryOnGroup(group *models.MonitorOndutyGroup) {
	// 先拼接今天的日期
	todayString := time.Now().Format("2006-01-02")

	// 判断是否已经设置过了
	dbHistoryToday, _ := models.GetMonitorOndutyHistoryByOndutyGroupIdAndDay(group.ID, todayString)
	if dbHistoryToday.OnDutyUserId > 0 {
		return
	}
	// 到这里说明 没人填充，我要处理
	// 查换班表
	dbChange, _ := models.GetMonitorOndutyChangeByOndutyGroupIdAndDay(group.ID, todayString)
	if dbChange.ID > 0 {
		// 说明有人之前换班了，就设置它为历史
		history := models.MonitorOndutyHistory{
			OndutyGroupId: group.ID,
			DateString:    todayString,
			OnDutyUserId:  dbChange.OnDutyUserId,
			OriginUserId:  dbChange.OriginUserId,
		}
		err := history.CreateOne()
		if err != nil {
			cm.Sc.Logger.Error("创建值班历史结论失败",
				zap.Error(err),
				zap.Any("值班组", group.Name),
				zap.Any("日期", todayString),
			)
			return
		}
		return
	}

	// 往前查询一天 说明换班表也没有 说明需要生成了

	yestoday := common.GetDayAgoDate(-1)
	dbHistoryYestoday, _ := models.GetMonitorOndutyHistoryByOndutyGroupIdAndDay(group.ID, yestoday)
	// 判断是否需要换班 最近一个周期的记录
	// 如果昨天的人是换班的，那么就得用它之前的人
	if dbHistoryYestoday.OriginUserId > 0 {
		dbHistoryYestoday.OndutyGroupId = dbHistoryYestoday.OriginUserId
	}

	startDay := common.GetDayAgoDate(-1 * group.ShiftDays)

	historys, err := models.GetMonitorOndutyHistoryByOnDutyGroupIdAndTimeRange(int(group.ID), startDay, yestoday)
	if err != nil {
		cm.Sc.Logger.Error("查询值班历史结论失败",
			zap.Error(err),
			zap.Any("值班组", group.Name),
			zap.Any("日期", todayString),
		)
		return
	}
	needChange := false
	yijingzhibantianshu := 0
	for _, his := range historys {
		his := his
		if his.OnDutyUserId == dbHistoryYestoday.OnDutyUserId {
			yijingzhibantianshu++
		}
	}

	if yijingzhibantianshu == group.ShiftDays {
		needChange = true
	}

	var onDutyUserId uint
	// 昨天有可能是人为换班的人 ，都是按昨天生成后面的人，如果基准换了，后面就都要换
	if dbHistoryYestoday.ID == 0 {
		// 昨天也没人设置
		// 就把 值班组 第一个人 设置为今天
		onDutyUserId = group.Members[0].ID
	} else {

		if needChange {
			// 如果需要换班 ，那么找昨天 值班人的下一位
			// 有的话，找到数组里的下一个
			targetIndex := 0
			for index, user := range group.Members {
				index := index
				user := user

				if user.ID == dbHistoryYestoday.OnDutyUserId {
					targetIndex = index + 1
					break
				}
			}
			if targetIndex == len(group.Members) {
				targetIndex = len(group.Members) - 1
			}

			onDutyUserId = group.Members[targetIndex].ID
		} else {
			onDutyUserId = dbHistoryYestoday.OnDutyUserId
		}

	}

	history := models.MonitorOndutyHistory{
		OndutyGroupId: group.ID,
		DateString:    todayString,
		OnDutyUserId:  onDutyUserId,
	}
	err = history.CreateOne()
	if err != nil {
		cm.Sc.Logger.Error("创建值班历史记录失败",
			zap.Error(err),
			zap.Any("值班组", group.Name),
			zap.Any("日期", todayString),
		)
		return
	}
	return
}
